﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace iNet.Tasks
{
	/// <summary>
	/// 包含多個子工作的組合工作。
	/// </summary>
	public class CompoundTask : Task
	{
		#region 欄位
		readonly List<Task> _ChildTaskList = new List<Task>();
		#endregion
		#region 建構子
		/// <summary>
		/// 初始化新的 CompoundTask 執行個體。
		/// </summary>
		public CompoundTask()
		{ }
		/// <summary>
		/// 初始化新的 CompoundTask 執行個體。
		/// </summary>
		/// <param name="childTasks">包含的子工作。</param>
		public CompoundTask(IEnumerable<Task> childTasks)
		{
			if (childTasks != null)
				_ChildTaskList.AddRange(childTasks);
		}
		#endregion
		#region ChildTasks
		/// <summary>
		/// 取得或設定包含的子工作。
		/// </summary>
		public IEnumerable<Task> ChildTasks
		{
			get
			{
				return _ChildTaskList.ToArray();
			}
			set
			{
				lock (this.SyncRoot)
				{
					if (this.State != TaskState.Initializing)
						throw new InvalidOperationException();
					_ChildTaskList.Clear();
					if (value != null)
						_ChildTaskList.AddRange(value);
				}
			}
		}
		#endregion
		#region Execute
		/// <summary>
		/// 執行工作。
		/// </summary>
		/// <param name="version">工作版本。</param>
		/// <returns>True 表示工作執行成功，False 表示執行失敗。</returns>
		protected override bool Execute(TaskVersion version)
		{
			//初始化
			this.ReportProgress(version, 0);

			//執行工作
			int childTaskCount = _ChildTaskList.Count;
			if (childTaskCount > 0)
			{
				//準備事件處理方法
				int numOfExecutedTasks = 0;
				EventHandler<TaskProgressChangedEventArgs> progressChangedHandler = (sender, e) =>
				{
					double? progress = e.Progress;
					if (progress != null)
					{
						progress = ((numOfExecutedTasks * 100.0 / childTaskCount) + (progress.Value / childTaskCount));
						this.ReportProgress(version, progress);
					}
				};

				//執行工作
				for (int i = 0; i < childTaskCount; ++i)
				{
					Task childTask = _ChildTaskList[i];
					childTask.ProgressChanged += progressChangedHandler;
					try
					{
						//中斷確認
						if (this.IsCanceling)
							return true;

						//執行工作
						this.ExecuteChildTask(version, childTask);
					}
					catch (Exception ex)
					{ }
					finally
					{
						++numOfExecutedTasks;
						this.ReportProgress(version, (numOfExecutedTasks * 100.0 / childTaskCount));
						childTask.ProgressChanged -= progressChangedHandler;
					}
				}
			}

			//完成
			this.ReportProgress(version, 100);
			return true;
		}
		#endregion
		#region ResetOverride
		/// <summary>
		/// 重設工作狀態。
		/// </summary>
		protected override void ResetOverride()
		{
			base.ResetOverride();
			_ChildTaskList.Clear();
		}
		#endregion
	}
}
